#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <mysql/mysql.h>
#include <errno.h>

#include "../inc/cJSON.h"
#include "../inc/tcp.h"
#include "../inc/agreement.h"
#include "../inc/login.h"

static void deliver_message_to_user(client_info_p client, const char *target_id, const char *message_id);
static void search_message_by_ids(MYSQL *db_conn, const char *target_id, const char *message_id, char *resp_buf);

// 处理私聊指令
void handle_private_chat_cmd(client_info_p client, cJSON *root, cJSON *response)
{
    // 从JSON中获取payload对象
    cJSON *payload = cJSON_GetObjectItem(root, "payload");
    if (!payload || !cJSON_IsObject(payload))
    {
        cJSON_AddNumberToObject(response, "code", PRIVATE_CHAT_ERROR_PARAM);
        cJSON_AddStringToObject(response, "message", "私聊缺少必要的payload字段");
        return;
    }

    cJSON *target_id_json = cJSON_GetObjectItem(payload, "target_id");
    cJSON *content_json = cJSON_GetObjectItem(payload, "content");
    cJSON *msg_type_json = cJSON_GetObjectItem(payload, "type");
    cJSON *client_msg_id_json = cJSON_GetObjectItem(payload, "message_id");
    cJSON *chat_type_json = cJSON_GetObjectItem(payload, "chat_type");
    cJSON *client_send_time_json = cJSON_GetObjectItem(payload, "send_time"); // 修正字段名

    // 检查必要参数是否存在且类型正确
    if (!target_id_json || !cJSON_IsString(target_id_json) ||
        !content_json || !cJSON_IsString(content_json) ||
        !msg_type_json || !cJSON_IsString(msg_type_json) ||
        !chat_type_json || !cJSON_IsString(chat_type_json) ||
        !client_send_time_json || !cJSON_IsString(client_send_time_json))
    {
        cJSON_AddNumberToObject(response, "code", PRIVATE_CHAT_ERROR_PARAM);
        cJSON_AddStringToObject(response, "message", "私聊payload缺少必要参数或参数类型错误");
        return;
    }

    // 提取字段值
    const char *target_id = target_id_json->valuestring;
    const char *content = content_json->valuestring;
    const char *message_type = msg_type_json->valuestring;
    const char *chat_type = chat_type_json->valuestring;
    const char *client_message_id = client_msg_id_json ? client_msg_id_json->valuestring : NULL;
    const char *client_send_time = client_send_time_json->valuestring;

    // 获取当前服务器时间（用于create_time）
    char server_time[32];
    time_t now = time(NULL);
    struct tm *t = localtime(&now);
    strftime(server_time, sizeof(server_time), "%Y-%m-%d %H:%M:%S", t);

    // 准备SQL语句，存储客户端发送时间和服务器创建时间
    char sql[1024];
    snprintf(sql, sizeof(sql),
             "INSERT INTO im_messages ("
             "message_id, chat_type, sender_userid, target_id, "
             "message_content, message_type, send_time, create_time, is_read"
             ") VALUES ("
             "'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0"
             ");",
             client_message_id, chat_type, client->userid, target_id,
             content, message_type, client_send_time, server_time);

    if (mysql_query(client->db_conn, sql) != 0)
    {
        cJSON_AddNumberToObject(response, "code", PRIVATE_CHAT_ERROR_DB);
        cJSON_AddStringToObject(response, "message", "消息存储失败");
        return;
    }

    // 构建成功响应
    cJSON_AddNumberToObject(response, "code", PRIVATE_CHAT_SUCCESS_RECV_FROM_CLIENT);
    cJSON_AddStringToObject(response, "message", "消息发送成功");

    // 将消息发送给目标用户
    deliver_message_to_user(client, target_id, client_message_id);
}

// 将消息发送给目标用户
static void deliver_message_to_user(client_info_p client, const char *target_id, const char *message_id)
{
    int recipient_fd = get_user_online_fd(client, target_id);
    char resp_buf[1024];

    if (recipient_fd > 0)
    {
        search_message_by_ids(client->db_conn, target_id, message_id, resp_buf);
        send_message_to_client(recipient_fd, resp_buf);
    }
}

// 按target_id和message_id查询消息，查询成功标记消息为已读
static void search_message_by_ids(MYSQL *db_conn, const char *target_id, const char *message_id, char *resp_buf)
{
    // 1. 入参校验：排除空指针/空字符串
    if (!db_conn || !target_id || !strlen(target_id) || !message_id || !strlen(message_id))
        return;

    char sql[1024] = {0};
    MYSQL_RES *result = NULL;
    MYSQL_ROW row = NULL;
    cJSON *root = NULL;
    cJSON *payload = NULL;

    // -------------------------- 查询消息详情 --------------------------
    snprintf(sql, sizeof(sql),
             "SELECT message_id, sender_userid, target_id, message_content, "
             "message_type, send_time, chat_type "
             "FROM im_messages "
             "WHERE target_id = '%s' AND message_id = '%s' LIMIT 1;",
             target_id, message_id);

    if (mysql_query(db_conn, sql) != 0)
        goto cleanup;

    result = mysql_store_result(db_conn);
    if (!result || mysql_num_rows(result) == 0)
        goto cleanup;

    row = mysql_fetch_row(result);
    if (!row)
        goto cleanup;

    // -------------------------- 更新is_read为1（标记已读） --------------------------
    snprintf(sql, sizeof(sql),
             "UPDATE im_messages "
             "SET is_read = 1 "
             "WHERE target_id = '%s' AND message_id = '%s';",
             target_id, message_id);
    mysql_query(db_conn, sql); // 不处理结果，仅执行更新

    // -------------------------- 构建指定格式JSON --------------------------
    root = cJSON_CreateObject();
    if (!root)
        goto cleanup;
    cJSON_AddStringToObject(root, "type", "private_chat");
    cJSON_AddNumberToObject(root, "code", PRIVATE_CHAT_SUCCESS);
    cJSON_AddStringToObject(root, "message", "消息发送成功");

    payload = cJSON_CreateObject();
    if (!payload)
        goto cleanup;
    cJSON_AddItemToObject(root, "payload", payload);

    // 填充payload字段
    cJSON_AddStringToObject(payload, "message_id", row[0] ? row[0] : "");
    cJSON_AddStringToObject(payload, "sender_userid", row[1] ? row[1] : "");
    cJSON_AddStringToObject(payload, "target_id", row[2] ? row[2] : "");
    cJSON_AddStringToObject(payload, "content", row[3] ? row[3] : "");
    cJSON_AddStringToObject(payload, "type", row[4] ? row[4] : "");
    cJSON_AddStringToObject(payload, "send_time", row[5] ? row[5] : "");
    cJSON_AddStringToObject(payload, "chat_type", row[6] ? row[6] : "");

    // 转换为JSON字符串
    generate_response_string(root, resp_buf);

// -------------------------- 资源清理 --------------------------
cleanup:
    if (result)
        mysql_free_result(result);
    if (root)
        cJSON_Delete(root);
}
